package com.xnx3.j2ee.util;

import org.apache.commons.net.ftp.FTPClient;
import com.xnx3.FileUtil;
import com.xnx3.StringUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
/**
 * FTP工具类
 * 需要使用  commons-net v3.3
* @author 周瑞宝,管雷鸣整理
* @date 2022/07/09
*/
public class FTPUtil {
	FTPClient ftpClient;
	private String hostname;	//ip或域名地址
	private int port = 21;		//端口默认21
	private String username;	//用户名
	private String password;	//密码
	
	private String currentPath;	//当前所在的FTP的目录，这个目录并不是实际的在服务器的目录，而是upload 中传入的filePath
	
	/**
	* 
	*/
	public FTPUtil(String hostname, int port, String username, String password) {
		this.hostname = hostname;
		this.port = port;
		this.username = username;
		this.password = password;
		
		ftpClient = new FTPClient();
		currentPath = "-1";
	}

	/**
	 * 上传
	 *
	 * @param hostname ip或域名地址
	 * @param port  端口
	 * @param username 用户名
	 * @param password 密码
	 * @param filePath 要将文件上传到ftp的哪个路径下,传入格式如 /web/root/ 
	 * @param inputStream 要上传文件的输入流
	 * @param fileName	设置上传之后的文件名 传入如:  a.html
	 * @return
	 */
	public boolean upload(String filePath, InputStream inputStream, String fileName) {
//		  //如果第一个字符是 / ,那么将其去掉,因为框架要求的传入格式是 web/root/ ,前面不能带 /
//		  if(filePath.indexOf("/") == 0) {
//			  filePath = filePath.substring(1, filePath.length());
//		  }

		int num = 0;	//尝试链接次数
		while(!ftpClient.isConnected() && num++ < 10) {
			//如果未建立链接，那么要打开链接
			if (connect(hostname, port, username, password)) {
				//打开成功
//				  ConsoleUtil.debug("FTP打开链接");
			}else {
				ConsoleUtil.debug("FTP未能打开链接。当前第"+num+"次尝试");
			}
		}
		if(!ftpClient.isConnected()) {
			ConsoleUtil.error("FTP未能打开链接!放弃");
			return false;
		}

		if(!this.currentPath.equals(filePath)) {
			//跟上次不在一个目录下，要先进入这个目录
			try {
				String serverAbsPath = ftpClient.printWorkingDirectory()+filePath;
				serverAbsPath = serverAbsPath.replaceAll("//", "/");	//去掉 //
//			  		boolean makeDirectory = ftpClient.makeDirectory("a12");
//			  		if(!makeDirectory) {
//			  			ConsoleUtil.debug("创建目录失败。服务器中实际目录："+serverAbsPath);
//			  		}
				if (!ftpClient.changeWorkingDirectory(serverAbsPath)) {
					ConsoleUtil.debug("FTP目录 "+filePath+" 进入返回false。可能是服务器权限有什么限定，多数情况下不影响文件上传。当然最终还要看文件是否传上去了。服务器中实际目录："+serverAbsPath);
				} else {
					ConsoleUtil.debug("进入FTP目录："+filePath+", 服务器中实际目录："+serverAbsPath);
				}

				this.currentPath = filePath;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		//上传
		return storeFile(ftpClient, fileName, inputStream);
	}
	
	public boolean upload(String filePath, String text, String fileName) {
		InputStream fileInputStream = null;
		try {
			fileInputStream = StringUtil.stringToInputStream(text, FileUtil.UTF8);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			ConsoleUtil.debug("stringToInputStream error.");
			return false;
		}
		return upload(filePath, fileInputStream, fileName);
	 }
	/**
	 * 断开连接
	 *
	 * @param ftpClient
	 * @throws Exception
	 */
	public static void disconnect(FTPClient ftpClient) {
		if (ftpClient.isConnected()) {
			try {
				ftpClient.disconnect();
				ConsoleUtil.info("已关闭连接");
			} catch (IOException e) {
				ConsoleUtil.info("没有关闭连接");
				e.printStackTrace();
			}
		}
	}
	/**
	 * 测试是否能连接
	 *
	 * @param ftpClient
	 * @param hostname  ip或域名地址
	 * @param port	  端口
	 * @param username  用户名
	 * @param password  密码
	 * @return 返回真则能连接
	 */
	public boolean connect(String hostname, int port, String username, String password) {
		boolean flag = false;
		try {
			//ftp初始化的一些参数
			ftpClient.connect(hostname, port);
			ftpClient.enterLocalPassiveMode();
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.setControlEncoding("UTF-8");
			if (ftpClient.login(username, password)) {
				ConsoleUtil.info("连接ftp成功");
				//ConsoleUtil.info(JSONArray.fromObject(ftpClient.listFiles()).toString());
				flag = true;
			} else {
				ConsoleUtil.info("连接ftp失败，可能用户名或密码错误");
				try {
					disconnect(ftpClient);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			ConsoleUtil.info("连接失败，可能ip或端口错误");
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 上传文件
	 *
	 * @param ftpClient
	 * @param  path		全路径。如home/public/a.txt
	 * @param fileInputStream 要上传的文件流
	 * @return
	 */
	public static boolean storeFile(FTPClient ftpClient, String path, InputStream fileInputStream) {
		boolean flag = false;
		try {
			if (ftpClient.storeFile(path, fileInputStream)) {
				flag = true;
			}
		} catch (IOException e) {
			ConsoleUtil.info("上传失败");
			e.printStackTrace();
		}
		return flag;
	}
	

	public static void main(String[] args) {
		int port = 21;
//		String hostname = "ftp.cntd12n.99aiji.net";
//		String username = "zrb5517";
//		String password = "7YLQDG4SHMQ9";
		
		String hostname = "192.168.31.237";
		String username = "test";
		String password = "ewbHbiSMAKZmWw3L";
		
		FTPUtil ftpTools = new FTPUtil(hostname, port, username, password);
//		boolean result = ftpTools.upload("/web/root/", "12345", "demo.html");
		boolean a = ftpTools.upload("/www/wwwroot/test/", "12345", "ha21.html");
		System.out.println(a);
	}
	
	
}
